<script setup lang="ts">
import { ref, computed } from "vue";
import { getAssetsFile } from "@visual/utils";
defineOptions({
  name: "leftCompWrapper"
});
const props = defineProps<{
  title?: string;
  hasCollapsed?: boolean;
  iconName?: string;
  noWrapper?: boolean;
}>();
const isCollapsed = defineModel({ type: Boolean });
const toggleCollapse = () => {
  isCollapsed.value = !isCollapsed.value;
};

let oldPaddingTop = ref("");
let oldPaddingBottom = ref("");
let oldOverflow = ref("");

const iconUrl = computed(() => {
  return getAssetsFile(props.iconName);
});
const collapseBeforeEnter = el => {
  oldPaddingBottom.value = el.style.paddingBottom;
  oldPaddingTop.value = el.style.paddingTop;
  el.style.paddingTop = "0";
  el.style.paddingBottom = "0";
  el.style.maxHeight = "0";
};

const collapseEnter = (el, done) => {
  oldOverflow.value = el.style.overflow;
  let elHeight = el.scrollHeight;
  if (elHeight > 0) {
    el.style.maxHeight = elHeight + "px";
  } else {
    el.style.maxHeight = "0";
  }
  el.style.paddingTop = oldPaddingTop.value;
  el.style.paddingBottom = oldPaddingBottom.value;
  el.style.overflow = "hidden";

  let onTransitionDone = function () {
    done();
    el.removeEventListener("transitionend", onTransitionDone, false);
    el.removeEventListener("transitioncancel", onTransitionDone, false);
  };
  el.addEventListener("transitionend", onTransitionDone, false);
  el.addEventListener("transitioncancel", onTransitionDone, false);
};
const collapseAfterEnter = el => {
  el.style.maxHeight = "";
  el.style.overflow = oldOverflow.value;
};
const collapseBeforeLeave = el => {
  oldPaddingBottom.value = el.style.paddingBottom;
  oldPaddingTop.value = el.style.paddingTop;
  oldOverflow.value = el.style.overflow;
  el.style.maxHeight = el.scrollHeight + "px";
  el.style.overflow = "hidden";
};

const collapseLeave = (el, done) => {
  if (el.scrollHeight !== 0) {
    el.style.maxHeight = "0";
    el.style.paddingBottom = "0";
    el.style.paddingTop = "0";
  }

  let onTransitionDone = function () {
    done();
    el.removeEventListener("transitionend", onTransitionDone, false);
    el.removeEventListener("transitioncancel", onTransitionDone, false);
  };
  el.addEventListener("transitionend", onTransitionDone, false);
  el.addEventListener("transitioncancel", onTransitionDone, false);
};
const collapseAfterLeave = el => {
  el.style.maxHeight = "";
  el.style.overflow = oldOverflow.value;
  el.style.paddingBottom = oldPaddingBottom.value;
  el.style.paddingTop = oldPaddingTop.value;
  oldOverflow.value = oldPaddingBottom.value = oldPaddingTop.value = "";
};
</script>

<template>
  <div v-if="!noWrapper" class="modpx-wrapper">
    <div class="modpx-title">
      <div v-if="title" class="flex justify-start items-center mb-[8px]">
        <img v-if="iconName" class="w-[20px] h-[20px] mr-[12px]" :src="iconUrl" />
        <div>
          {{ title }}
        </div>
      </div>
      <px-icon v-if="hasCollapsed" :class="{ 'arrow-rotate': isCollapsed }" class="arrow" @click="toggleCollapse"><ArrowUp /></px-icon>
    </div>
    <transition
      name="collapse-transition"
      @before-enter="collapseBeforeEnter"
      @enter="collapseEnter"
      @after-enter="collapseAfterEnter"
      @before-leave="collapseBeforeLeave"
      @leave="collapseLeave"
      @after-leave="collapseAfterLeave"
    >
      <slot />
    </transition>
  </div>
  <slot v-else />
</template>

<style lang="scss" scoped>
.modpx-wrapper {
  width: 100%;
  padding: 16px 20px;
  margin-bottom: 8px;
  background-color: #fff;
  border-radius: 8px;

  .content-wrapper {
    overflow: hidden;
  }

  .modpx-title {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 32px;
    font-size: 16px;
    font-weight: 700;
    line-height: 24px;
    color: #000;
    box-shadow: inset 0 -1px 0 0 rgb(0 0 0 / 10%);
  }

  .collapse-transition-enter-active,
  .collapse-transition-leave-active {
    transition:
      height 0.3s ease-in-out,
      padding 0.3s ease-in-out,
      max-height 0.3s ease-in-out;
  }

  .arrow-rotate {
    transform: rotate(180deg);
  }

  .arrow {
    transition: transform 0.3s ease-in-out;
  }
}
</style>
